package com.zhaokuner.parentstarter.ctrladaptor;

import com.zhaokuner.parentstarter.ctrladaptor.annotation.CtrlAdaptorAutowired;
import lombok.extern.log4j.Log4j2;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanCreationException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.stereotype.Component;

import java.lang.reflect.Field;
import java.lang.reflect.Proxy;

/**
 * <p>
 * Description:为ctrl adaptor 生成 http代理对象
 * <p>
 * Copyright: 天津联想协同科技有限公司
 * <p>
 *
 * @author 赵希坤 zhaoxikun
 * @date 2021/2/16 23:20
 */
@Log4j2
@Component
public class CtrlAdaptorBeanPostProcessor implements BeanPostProcessor {

    public static final String PUBLIC = "public";

    @Value("${project.app}")
    private String projectApp;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        //判断是否为公有
        if (!PUBLIC.equals(projectApp)) {
            return bean;
        }
        //公有的进行远程调用
        Class<?> objClz;
        if (AopUtils.isAopProxy(bean)) {
            objClz = AopUtils.getTargetClass(bean);
        } else {
            objClz = bean.getClass();
        }

        try {
            for (Field field : objClz.getDeclaredFields()) {
                CtrlAdaptorAutowired reference = field.getAnnotation(CtrlAdaptorAutowired.class);
                if (reference != null) {
                    log.info(" CtrlAdaptor Proxy {}.{}", beanName, field.getName());
                    Object referenceBean = Proxy.newProxyInstance(field.getType().getClassLoader(),
                            new Class<?>[]{field.getType()},
                            new CtrlAdaptorInvocationHandler());
                    field.setAccessible(true);
                    field.set(bean, referenceBean);
                }
            }
        } catch (Exception e) {
            throw new BeanCreationException(beanName, e);
        }
        return bean;
    }

}
